package com.geek.gateway.config;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.geek.common.utils.JwtUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

@Component
public class JwtAuthGlobalFilter implements GlobalFilter, Ordered {

    // 不需要拦截的路径
    private static final String[] WHITE_LIST = {
            "/geek-user/user/login",      // 匹配用户服务登录
    };

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getPath().toString();

        // 检查白名单
        if (isWhiteList(path)) {
            return chain.filter(exchange);
        }

        // 从请求头获取Token
        String token = request.getHeaders().getFirst("Authorization");
        if (token == null) {
            return errorResponse(exchange.getResponse(), 10001, "缺少token");
        }

        // 检查Token格式
        if (!token.startsWith("Bearer ")) {
            return errorResponse(exchange.getResponse(), 10002, "token不合法");
        }

        // 验证Token
        token = token.substring(7); // 去掉Bearer前缀
        if (!JwtUtils.validateToken(token)) {
            return errorResponse(exchange.getResponse(), 10003, "无效的token");
        }

        // 将用户信息添加到请求头
        String userId = JwtUtils.getClaim(token, "userId");
        String role = JwtUtils.getClaim(token, "role");

        ServerHttpRequest newRequest = request.mutate()
                .header("X-User-Id", userId)
                .header("X-User-Role", role)
                .build();

        return chain.filter(exchange.mutate().request(newRequest).build());
    }

    @Override
    public int getOrder() {
        return -100; // 设置过滤器优先级
    }

    private boolean isWhiteList(String path) {
        for (String whitePath : WHITE_LIST) {
            if (path.startsWith(whitePath)) {
                return true;
            }
        }
        return false;
    }

    private Mono<Void> errorResponse(ServerHttpResponse response, int code, String message) {
        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        response.getHeaders().setContentType(MediaType.APPLICATION_JSON);

        Map<String, Object> map = new HashMap<>();
        map.put("code", code);
        map.put("message", message);

        try {
            byte[] bytes = objectMapper.writeValueAsBytes(map);
            DataBuffer buffer = response.bufferFactory().wrap(bytes);
            return response.writeWith(Mono.just(buffer));
        } catch (JsonProcessingException e) {
            // 如果JSON序列化失败，返回原始错误信息
            byte[] bytes = ("{\"code\":" + code + ",\"message\":\"" + message + "\"}").getBytes(StandardCharsets.UTF_8);
            DataBuffer buffer = response.bufferFactory().wrap(bytes);
            return response.writeWith(Mono.just(buffer));
        }
    }
}